ext.define('extension.filterview', function() {

var messages = extension.messages;
var utils = extension.utils;
var slider = extension.slider;
var filterset;
var views = {};
var url;

var view = {
    init: function() {
        relayEvent($(this.id).querySelector('.listbox.patterns'), 'click', '.enable,.delete', onListbox.bind(this));
        relayEvent($(this.id).querySelector('.console'), 'keydown', '.input', onInput.bind(this));
        relayEvent($(this.id).querySelector('.status-bar'), 'click', '.statusbar-item', onStatusbar.bind(this));
        relayEvent($(this.id).querySelector('.console-statusbar'), 'click', '.statusbar-item', onStatusbar.bind(this));
        $(this.id).querySelector('.splitter').addEventListener('mousedown', onSlide);
        $(this.id).querySelector('.console-input').addEventListener('click', onConsole.bind(this));
        $(this.id).querySelector('.statusbar-console').click();
        if (this.live)
            $(this.id).querySelector('.statusbar-live').click();
    },
    update: function() {
        var g = [], h;
        this.filters.some(function(f, i) {
            if (f.root && utils.regexp(f.root).test(url)) {
                h = i;
                g = f.patterns;
                return true;
            }
        });

        if (g.length === 0) {
            this.clear();
            return;
        }

        this.index = h;

        this.patterns(g);
    },
    pattern: function(t) {
        var b = this.filters.some(function(f, i) {
            if (f.root && utils.regexp(f.root).test(url)) {
                this.filters[i].patterns.push({
                    enabled: 1,
                    pattern: t
                });
                return true;
            }
        }, this);

        if (!b) {
            this.filters.push({
                root: utils.authority(url),
                name: 'new group',
                enabled: true,
                patterns: [{pattern: t, enabled: 1}]
            });
        }

        filterset.set(this.id, this.filters);

        this.update();
    },
    load: function(g) {
        while (this.filters[0])
            this.filters.pop();
        for (var i = 0; i < g.length; i++)
            this.filters.push(g[i]);
        this.update();
    },
    patterns: function(g) {
        var l = $(this.id).querySelector('.listbox.patterns');

        l.textContent = '';

        var n, m = $x('pattern');
        for (var i = 0; i < g.length; i++) {
            n = m.cloneNode(true);
            n.querySelector('input').checked = g[i].enabled;
            n.querySelector('.text').textContent = g[i].pattern;
            l.appendChild(n);
        }

        if (l.lastElementChild)
            l.lastElementChild.scrollIntoView();
    },
    clear: function() {
        $(this.id).querySelector('.listbox.patterns').textContent = '';
    }
};

function onConsole(e) {
    e.currentTarget.querySelector('.console .input').focus();
}

function onListbox(e) {
    var i = getChildPosition(e.relayTarget.parentNode);

    if (e.relayTarget.classList.contains('delete')) {
        var p = this.filters[this.index].patterns.splice(i, 1)[0];

        filterset.set(this.id, this.filters);

        if (this.live) {
            messages.send('filters-update', [{
                type: utils.stringMap(this.id),
                enabled: 0,
                pattern: p.pattern
            }]);
        }

        e.currentTarget.removeChild(e.relayTarget.parentNode);
    }

    if (e.relayTarget.classList.contains('enable')) {
        this.filters[this.index].patterns[i].enabled = +e.relayTarget.checked;

        filterset.set(this.id, this.filters);

        if (this.live) {
            messages.send('filters-update', [{
                type: utils.stringMap(this.id),
                enabled: +e.relayTarget.checked,
                pattern: e.relayTarget.parentNode.querySelector('.text').textContent
            }]);
        }

        return true;
    }
}

function onInput(e) {
    switch (e.keyIdentifier) {
        case 'Enter':
            e.preventDefault();
            var q = e.relayTarget.textContent.trim();
            e.relayTarget.textContent = '';
            e.relayTarget.focus();
            if (q) {
                this.history.put(q);
                this.pointer = this.history.size();

                var t = $x('output');
                var n = e.currentTarget.querySelector('.console-messages');
                var p = e.currentTarget.querySelector('.console-input');

                var o, m = q, c = 'command';

                var l = $(this.id).querySelectorAll('.listbox.patterns .list-item .text');
                for (var i = 0; i < l.length; i++) {
                    if (l[i].textContent === q) {
                        o = t.cloneNode(true);
                        o.querySelector('.text').textContent = q;
                        o.querySelector('.text').classList.add('command');
                        o.querySelector('.text').classList.add('invalid');
                        n.insertBefore(o, p);
                        if (q.length > 32)
                            m = q.substr(0, 14) + '...' + q.substr(-14);
                        m = utils.format(utils.strings.PTRNDUP, m);
                        c = 'error';
                        break;
                    }
                }

                o = t.cloneNode(true);
                o.querySelector('.text').textContent = m;
                if (c !== 'error')
                    o.querySelector('.text').classList.add('result');
                o.querySelector('.text').classList.add(c);

                n.insertBefore(o, p);
                p.scrollIntoView();

                if (c !== 'error') {
                    this.pattern(q);
                    if (this.live) {
                        messages.send('filters-update', [{
                            type: utils.stringMap(this.id),
                            enabled: 1,
                            pattern: q
                        }]);
                    }
                }
            }
            break;
        case 'Up':
        case 'Down':
            e.preventDefault();
            this.pointer += e.keyIdentifier == 'Up' ? -1 : 1;
            this.pointer = Math.max(0, Math.min(this.history.size() - 1, this.pointer));
            e.relayTarget.textContent = this.history.peek(this.pointer) || '';
            break;
    }

    return true;
}

function onStatusbar(e) {
    if (e.relayTarget.classList.contains('statusbar-console')) {
        if (this.resizing)
            return;

        this.resizing = true;

        var t = this;
        if (!this.deployed) {
            slider.expand($(this.id).querySelector('.splitter'), function() {
                $(t.id).querySelector('.console').classList.remove('collapsed');
                $(t.id).querySelector('.console .console-input').scrollIntoView();
                $(t.id).querySelector('.console .input').focus();
                delete t.resizing;
            });
            e.relayTarget.classList.add('active');
        }
        else {
            $(this.id).querySelector('.console').classList.add('collapsed');
            slider.collapse($(this.id).querySelector('.splitter'), function() {
                delete t.resizing;
            });
            e.relayTarget.classList.remove('active');
        }

        this.deployed = !this.deployed;

        e.relayTarget.setAttribute('title', utils.format(utils.strings.CLPSMODE, this.deployed ? 'Collapse' : 'Expand'));
    }

    if (e.relayTarget.classList.contains('statusbar-delete')) {
        var g = this.filters.splice(this.index, 1)[0];

        filterset.set(this.id, this.filters);

        if (g && g.patterns.length > 0) {
            if (this.live) {
                var k = utils.stringMap(this.id);
                messages.send('filters-update', g.patterns.map(function(i) {
                    return {
                        type: k,
                        enabled: 0,
                        pattern: i.pattern
                    };
                }));
            }
        }

        this.clear();
    }

    if (e.relayTarget.classList.contains('statusbar-live')) {
        var str = ['Disable', 'Enable'];
        this.live = e.relayTarget.classList.toggle('active');
        e.relayTarget.setAttribute('title', utils.format(utils.strings.LIVEMODE, str[+!this.live]));
    }

    if (e.relayTarget.classList.contains('statusbar-clear')) {
        this.history.clear();
        this.pointer = -1;
        var elms = $(this.id).querySelectorAll('.console-messages .text');
        for (var i = 0; i < elms.length; i++)
            elms[i].parentNode.removeChild(elms[i]);
    }
}

function onSlide(e) {
    e.preventDefault();
    utils.glass('y', slider.create(e));
}

function getFilterView(k) {
    if (views[k] == null) {
        views[k] = createFilterView(k);
        views[k].init();
    }
    return views[k];
}

function createFilterView(k) {
    return Object.create(view, {
        id: { value: k },
        index: { value: -1, writable: true },
        live: { value: true, writable: true },
        filters: { value: [] },
        history: { value: utils.queue() },
        pointer: { value: -1, writable: true }
    });
}

function resetViews() {
    getFilterView('patternlistB').clear();
    getFilterView('patternlistD').clear();
}

function updateViews(obj) {
    url = obj.url;
    filterset = obj.filters;
    var keywordsB = getFilterView('patternlistB');
    keywordsB.load(filterset.get('patternlistB'));
    var keywordsD = getFilterView('patternlistD');
    keywordsD.load(filterset.get('patternlistD'));
}

return {
    reset: resetViews,
    update: updateViews
};

});
